package com.dieusoft.box.bill.controller;


import com.alibaba.fastjson.JSONObject;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.conditions.update.UpdateWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.dieusoft.box.bill.entity.PayApplyInfo;
import com.dieusoft.box.bill.service.IPayApplyService;
import com.dieusoft.box.bill.vo.InvoiceQueryVO;
import com.dieusoft.box.bill.vo.PayApplyInfoVO;
import com.dieusoft.box.bill.vo.PayApplyQueryVO;
import com.dieusoft.box.ship.entity.ShipExport;
import com.dieusoft.box.ship.service.ShipExportService;
import com.dieusoft.box.trade.entity.CostInfo;
import com.dieusoft.box.trade.entity.JzxTrade;
import com.dieusoft.box.trade.service.ICostInfoService;
import com.dieusoft.box.trade.service.IJzxTradeService;
import io.swagger.annotations.Api;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.apache.shiro.SecurityUtils;
import org.jeecg.common.api.vo.Result;
import org.jeecg.common.system.vo.LoginUser;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.*;

import javax.transaction.Transactional;
import java.time.LocalDate;
import java.time.format.DateTimeFormatter;
import java.util.Arrays;
import java.util.Collections;
import java.util.Date;
import java.util.List;
import java.util.stream.Collectors;

/**
 * @Description: 付款管理
 * @Author: dongw
 * @Date: 2021-03-22
 * @Version: V1.0
 */
@Api(tags = "付款管理")
@RestController
@RequestMapping("/payapply")
@Slf4j
public class PayApplyController {

    @Autowired
    private ShipExportService shipExportService;

    @Autowired
    private IJzxTradeService jzxTradeService;

    @Autowired
    private ICostInfoService costInfoService;

    @Autowired
    private IPayApplyService payApplyService;

    /**
     * 海运费用明细查询
     *
     * @param invoiceQueryVo
     * @return
     */
    @GetMapping(value = "/query/list")
    public Result<?> queryPageList(InvoiceQueryVO invoiceQueryVo) {
        LoginUser sysUser = (LoginUser) SecurityUtils.getSubject().getPrincipal();
        QueryWrapper<ShipExport> shipExportQueryWrapper = new QueryWrapper<>();
        shipExportQueryWrapper.eq("sys_org_code", sysUser.getOrgCode());
        if (StringUtils.isNotBlank(invoiceQueryVo.getMainOffNumber())) {
            shipExportQueryWrapper.like("main_off_number", invoiceQueryVo.getMainOffNumber());
        }
        if (StringUtils.isNotBlank(invoiceQueryVo.getOtherOffNumber())) {
            shipExportQueryWrapper.like("other_off_number", invoiceQueryVo.getOtherOffNumber());
        }
        if (StringUtils.isNotBlank(invoiceQueryVo.getCustomerNumber())) {
            shipExportQueryWrapper.like("customer_number", invoiceQueryVo.getCustomerNumber());
        }
        if (StringUtils.isNotBlank(invoiceQueryVo.getEtdEnd()) && StringUtils.isNotBlank(invoiceQueryVo.getEtdStart())) {
            shipExportQueryWrapper.between("etd", invoiceQueryVo.getEtdStart(), invoiceQueryVo.getEtdEnd());
        }

        List<ShipExport> shipExportList = shipExportService.list(shipExportQueryWrapper);

        List<String> ids = shipExportList.stream().map(ShipExport::getId).collect(Collectors.toList());

        if (ids.size() == 0) {
            return Result.OK(Collections.EMPTY_LIST);
        } else {
            QueryWrapper<CostInfo> costInfoQueryWrapper = new QueryWrapper<>();
//            costInfoQueryWrapper.eq("create_by", sysUser.getUsername());
            costInfoQueryWrapper.like("s_code", 3);
            costInfoQueryWrapper.like("type", "yf");

            costInfoQueryWrapper.in("buis_id", ids);
            if (StringUtils.isNotBlank(invoiceQueryVo.getSettlementCompany())) {
                costInfoQueryWrapper.like("settlement_company", invoiceQueryVo.getSettlementCompany());
            }
            if (StringUtils.isNotBlank(invoiceQueryVo.getCostName())) {
                costInfoQueryWrapper.like("cost_name", invoiceQueryVo.getCostName());
            }
            if (StringUtils.isNotBlank(invoiceQueryVo.getCurrency())) {
                costInfoQueryWrapper.like("currency", invoiceQueryVo.getCurrency());
            }
            List<CostInfo> costInfoList = costInfoService.list(costInfoQueryWrapper);
            return Result.OK(costInfoList);
        }

    }

    /**
     * 箱贸应付费用明细查询
     *
     * @param invoiceQueryVo
     * @return
     */
    @GetMapping(value = "/query/trade/list")
    public Result<?> queryTradePageList(InvoiceQueryVO invoiceQueryVo) {
        LoginUser sysUser = (LoginUser) SecurityUtils.getSubject().getPrincipal();
        QueryWrapper<JzxTrade> jzxTradeQueryWrapper = new QueryWrapper<>();
        jzxTradeQueryWrapper.eq("sys_org_code", sysUser.getOrgCode());

        if (StringUtils.isNotBlank(invoiceQueryVo.getContainerNumber())) {
            jzxTradeQueryWrapper.like("container_number", invoiceQueryVo.getContainerNumber());
        }

        if (StringUtils.isNotBlank(invoiceQueryVo.getCompanyName())) {
            jzxTradeQueryWrapper.like("company_name", invoiceQueryVo.getCompanyName());
        }

        if (StringUtils.isNotBlank(invoiceQueryVo.getCustomerNumber())) {
            jzxTradeQueryWrapper.like("customer_number", invoiceQueryVo.getCustomerNumber());
        }
        if (StringUtils.isNotBlank(invoiceQueryVo.getEtdEnd()) && StringUtils.isNotBlank(invoiceQueryVo.getEtdStart())) {
            jzxTradeQueryWrapper.between("etd", invoiceQueryVo.getEtdStart(), invoiceQueryVo.getEtdEnd());
        }

        List<JzxTrade> jzxTradeList = jzxTradeService.list(jzxTradeQueryWrapper);

        List<String> ids = jzxTradeList.stream().map(JzxTrade::getId).collect(Collectors.toList());

        if (ids.size() == 0) {
            return Result.OK(Collections.EMPTY_LIST);
        } else {
            QueryWrapper<CostInfo> costInfoQueryWrapper = new QueryWrapper<>();
//            costInfoQueryWrapper.eq("create_by", sysUser.getUsername());
            costInfoQueryWrapper.like("s_code", 3);
            costInfoQueryWrapper.like("type", "yf");

            costInfoQueryWrapper.in("buis_id", ids);
            if (StringUtils.isNotBlank(invoiceQueryVo.getSettlementCompany())) {
                costInfoQueryWrapper.like("settlement_company", invoiceQueryVo.getSettlementCompany());
            }
            if (StringUtils.isNotBlank(invoiceQueryVo.getCostName())) {
                costInfoQueryWrapper.like("cost_name", invoiceQueryVo.getCostName());
            }
            if (StringUtils.isNotBlank(invoiceQueryVo.getCurrency())) {
                costInfoQueryWrapper.like("currency", invoiceQueryVo.getCurrency());
            }
            List<CostInfo> costInfoList = costInfoService.list(costInfoQueryWrapper);
            return Result.OK(costInfoList);
        }

    }

    /**
     * 列表查询
     *
     * @param pageNo
     * @param pageSize
     * @return
     */
    @GetMapping(value = "/init/list")
    public Result list(PayApplyQueryVO payApplyQueryVO,
                       @RequestParam(name = "pageNo", defaultValue = "1") Integer pageNo,
                       @RequestParam(name = "pageSize", defaultValue = "10") Integer pageSize) {
        QueryWrapper<PayApplyInfo> queryWrapper = new QueryWrapper<>();
        if (StringUtils.isNotBlank(payApplyQueryVO.getPaySerial())) {
            queryWrapper.like("pay_serial", payApplyQueryVO.getPaySerial());
        }
        if (StringUtils.isNotBlank(payApplyQueryVO.getBillStatus())) {
            queryWrapper.like("bill_status", payApplyQueryVO.getBillStatus());
        }
        if (StringUtils.isNotBlank(payApplyQueryVO.getCreateBy())) {
            queryWrapper.like("create_by", payApplyQueryVO.getCreateBy());
        }
        if (StringUtils.isNotBlank(payApplyQueryVO.getSettlementCompany())) {
            queryWrapper.like("settlement_company", payApplyQueryVO.getSettlementCompany());
        }
        if (!StringUtils.isAnyBlank(payApplyQueryVO.getCreateDateStart(), payApplyQueryVO.getCreateDateEnd())) {
            queryWrapper.between("create_time", payApplyQueryVO.getCreateDateStart(), payApplyQueryVO.getCreateDateEnd());
        }

        Page<PayApplyInfo> page = new Page<PayApplyInfo>(pageNo, pageSize);
        IPage<PayApplyInfo> pageList = payApplyService.page(page, queryWrapper);
        return Result.OK(pageList);
    }


    /**
     * 编辑/保存
     *
     * @param payApplyInfoVO
     * @return
     */
    @PostMapping(value = "/{subType}")
    @Transactional(rollbackOn = Exception.class)
    public Result<?> add(@RequestBody PayApplyInfoVO payApplyInfoVO, @PathVariable String subType) {
        if ("save".equals(subType)) {
            if (StringUtils.isAnyBlank(payApplyInfoVO.getAmount(),
                    payApplyInfoVO.getCnyAmount(),
                    payApplyInfoVO.getRate(),
                    payApplyInfoVO.getCurrency(),
                    payApplyInfoVO.getCostIds())
            ) {
                return Result.error("付款申请保存失败，信息不全");
            }
            payApplyInfoVO.setPaySerial(getPayNumber());
            PayApplyInfo payApplyInfo = new PayApplyInfo();
            BeanUtils.copyProperties(payApplyInfoVO, payApplyInfo);
            boolean save = payApplyService.save(payApplyInfo);
            UpdateWrapper<CostInfo> costInfoUpdateWrapper = new UpdateWrapper<>();
            costInfoUpdateWrapper.set("s_code", 4);
            costInfoUpdateWrapper.set("status", "付款申请中");
            costInfoUpdateWrapper.eq("type", "yf");
            costInfoUpdateWrapper.in("id", Arrays.asList(payApplyInfo.getCostIds().split(",")));
            costInfoService.update(costInfoUpdateWrapper);
            return save ? Result.OK().success("付款申请保存成功") : Result.error("付款申请保存失败");
        } else if ("edit".equals(subType)) {
            if (StringUtils.isAnyBlank(payApplyInfoVO.getAmount(),
                    payApplyInfoVO.getCnyAmount(),
                    payApplyInfoVO.getRate(),
                    payApplyInfoVO.getCurrency(),
                    payApplyInfoVO.getCostIds(),
                    payApplyInfoVO.getId())
            ) {
                return Result.error("付款申请保存失败，信息不全");
            }

            PayApplyInfo payApplyInfo = new PayApplyInfo();
            BeanUtils.copyProperties(payApplyInfoVO, payApplyInfo);
            UpdateWrapper<CostInfo> costInfoUpdateWrapper = new UpdateWrapper<>();
            costInfoUpdateWrapper.set("s_code", 4);
            costInfoUpdateWrapper.set("status", "付款申请中");
            costInfoUpdateWrapper.eq("type", "yf");
            costInfoUpdateWrapper.in("id", Arrays.asList(payApplyInfo.getCostIds().split(",")));
            costInfoService.update(costInfoUpdateWrapper);

            UpdateWrapper<CostInfo> costInfoUpdateWrapper1 = new UpdateWrapper<>();
            costInfoUpdateWrapper1.set("s_code", 3);
            costInfoUpdateWrapper1.set("status", "审核成功");
            costInfoUpdateWrapper1.eq("type", "yf");
            costInfoUpdateWrapper1.in("id", payApplyInfoVO.getIds());
            costInfoService.update(costInfoUpdateWrapper1);

            boolean b = payApplyService.updateById(payApplyInfo);
            return b ? Result.OK().success("付款申请修改成功") : Result.error("付款申请修改失败");
        }
        return Result.error("无效的操作");
    }

    /**
     * 根据ID查询相应的费用明细数据
     *
     * @param id
     * @return
     */
    @GetMapping(value = "/query/costinfo")
    public Result list(String id) {
        if (StringUtils.isBlank(id)) {
            return Result.error("未发现要操作数据的单号");
        }
        PayApplyInfo payApplyInfo = payApplyService.getById(id);
        String costIds = payApplyInfo.getCostIds();
        List costIdsList = Arrays.asList(costIds.split(","));
        List costInfosByIds = costInfoService.getCostInfosByIds(costIdsList);
        return Result.OK(costInfosByIds);
    }

    /**
     * 审核通过/驳回
     *
     * @return
     */
    @PostMapping(value = "/action/{actionType}")
    @Transactional(rollbackOn = Exception.class)
    public Result action(@RequestBody JSONObject data, @PathVariable String actionType) {
        String id = data.getString("id");
        if (StringUtils.isNotBlank(id)) {
            LoginUser sysUser = (LoginUser) SecurityUtils.getSubject().getPrincipal();
            PayApplyInfo payApplyInfo = payApplyService.getById(id);
            payApplyInfo.setCheckUser(sysUser.getRealname());
            payApplyInfo.setCheckDate(new Date());
            if ("approved".equals(actionType)) {
                payApplyInfo.setStatus(2);
                UpdateWrapper<CostInfo> costInfoUpdateWrapper = new UpdateWrapper<>();
                costInfoUpdateWrapper.set("s_code", 5);
                costInfoUpdateWrapper.set("status", "结算中");
                costInfoUpdateWrapper.eq("type", "yf");
                costInfoUpdateWrapper.in("id", Arrays.asList(payApplyInfo.getCostIds().split(",")));
                costInfoService.update(costInfoUpdateWrapper);
            } else if ("reject".equals(actionType)) {
                payApplyInfo.setStatus(3);//驳回
            } else if ("revoke".equals(actionType)) {
                payApplyInfo.setStatus(1);//撤销审核
            }
            boolean b = payApplyService.updateById(payApplyInfo);
            return b ? Result.OK().success("操作成功") : Result.error("操作失败");
        } else {
            return Result.error("单据不存在");
        }
    }

    /**
     * 通过id删除
     *
     * @param id
     * @return
     */
    @DeleteMapping(value = "/delete")
    @Transactional(rollbackOn = Exception.class)
    public Result<?> delete(@RequestParam(name = "id", required = true) String id) {
        PayApplyInfo payApplyInfo = payApplyService.getById(id);
        if (null == payApplyInfo) {
            return Result.error("单据不存在");
        }
        String costIds = payApplyInfo.getCostIds();
        UpdateWrapper<CostInfo> costInfoUpdateWrapper = new UpdateWrapper<>();
        costInfoUpdateWrapper.set("s_code", 3);
        costInfoUpdateWrapper.set("status", "审核通过");
        costInfoUpdateWrapper.eq("type", "yf");
        costInfoUpdateWrapper.in("id", Arrays.asList(costIds.split(",")));
        costInfoService.update(costInfoUpdateWrapper);
        payApplyService.removeById(id);
        return Result.OK("删除成功!");
    }

    /**
     * 生成发票流水号
     *
     * @return
     */
    private synchronized String getPayNumber() {
        StringBuffer sb = new StringBuffer().append("PAYS");
        String yymmdd = DateTimeFormatter.ofPattern("yyMMdd").format(LocalDate.now());
        sb.append(yymmdd);
        String s = sb.toString();
        QueryWrapper queryWrapper = new QueryWrapper();
        queryWrapper.like("pay_serial", s);
        int count = payApplyService.count(queryWrapper);
        String billNumber = String.format("%0" + 4 + "d", count + 1);
        return sb.append(billNumber).toString();
    }
}
